﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;
using System.Drawing;

namespace TCCHWLib
{
    /// <summary>
    /// Computer Configuration Settings. Use 'Configuration.Instance' to access the singleton instance ...
    /// </summary>
    public class Configuration
    {
        #region Singleton Code
        private static Configuration m_Configuration = null;

        [XmlIgnore]
        public static Configuration Instance
        {
            get
            {
                if (m_Configuration == null)
                    m_Configuration = new Configuration();

                return Configuration.m_Configuration;
            }
            set { Configuration.m_Configuration = value; }
        }
        #endregion

        private const string m_FileName = "..\\..\\..\\config.txt";
        private int m_ProcessorsCount = 2;
        private Size m_SharedMemorySize = new Size(1, 1024);
        private Size m_DefaultCacheSize = new Size(1, 128);
        private int m_SignatureRegisterSize = 32;

        public int ProcessorsCount
        {
            get { return m_ProcessorsCount; }
            set { m_ProcessorsCount = value; }
        }
        public Size DefaultCacheSize
        {
            get { return m_DefaultCacheSize; }
            set { m_DefaultCacheSize = value; }
        }
        public Size SharedMemorySize
        {
            get { return m_SharedMemorySize; }
            set { m_SharedMemorySize = value; }
        }
        public int SignatureRegisterSize
        {
            get { return m_SignatureRegisterSize; }
            set { m_SignatureRegisterSize = value; }
        }

        private Configuration()
        {

        }

        public static void SaveConfiguration()
        {
            StreamWriter sw = new StreamWriter(m_FileName);
            PropertyInfo[] props = Instance.GetType().GetProperties();

            foreach (PropertyInfo p in props)
            {
                object[] o = p.GetCustomAttributes(false);
                if (o != null && o.Length > 0 && o[0] is XmlIgnoreAttribute)
                    continue;

                sw.WriteLine(String.Format("{0}={1}", p.Name, p.GetValue(Instance, null)));
            }
            sw.Close();
        }
        public static void LoadConfiguration()
        {
            if (!File.Exists(m_FileName))
            {
                throw new Exception("Cannot find configuration file.");
            }

            Type type = Instance.GetType();
            string propertyName, value;
            string[] temp;
            char[] splitChars = new char[] { '=' };
            PropertyInfo propertyInfo;

            string[] settings = File.ReadAllLines(m_FileName);
            foreach (string str in settings)
            {
                temp = str.Split(splitChars, StringSplitOptions.RemoveEmptyEntries);
                if (temp.Length == 2)
                {
                    propertyName = temp[0];
                    value = temp[1];
                    propertyInfo = type.GetProperty(propertyName);
                    if (propertyInfo != null)
                        SetProperty(propertyInfo, value);
                }
            }

            // Now the settings are loaded, prepare the chip ...
            Chip.Instance.ConstructChip();
        }

        private static void SetProperty(PropertyInfo propertyInfo, object value)
        {
            switch (propertyInfo.PropertyType.Name)
            {
                case "Int32":
                    propertyInfo.SetValue(Instance, Convert.ToInt32(value), null);
                    break;
                case "String":
                    propertyInfo.SetValue(Instance, value.ToString(), null);
                    break;
            }
        }

    }
}
